/*
Copyright (C) 1996-1997 GX Media, Inc.
Copyright (C) 2010 Ronie Salgado

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "stdafx.h"
#include "QPropEntity.h"
#include "QooleDoc.h"
#include "QMainFrame.h"
#include "QooleId.h"

BEGIN_EVENT_TABLE(QPropEntity, QPropSheetPage)
	EVT_SIZE(QPropEntity::OnSize)
	EVT_GRID_CELL_CHANGE(QPropEntity::OnCellChange)
END_EVENT_TABLE()

QPropEntity::QPropEntity(wxWindow *parent)
	: QPropSheetPage(parent)
{
	wxSizer *topSizer = new wxBoxSizer(wxVERTICAL);

	wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
	topSizer->Add(sizer, 0, wxALL|wxEXPAND, 5);
	wxStaticText *label = new wxStaticText(this, wxID_ANY, _("Class Name"));
	sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL);
	className = new wxTextCtrl(this, wxID_ANY);
	sizer->Add(className, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5);
	lightButton = new wxButton(this, QID_PROP_LIGHT_COLOR, _("Light Color"));
	lightButton->Enable(false);
	sizer->Add(lightButton, 0, 0);

	// Create the property list
	properties = new wxGrid(this, QID_PROP_ENTKEYS);
	//sizer = new wxBoxSizer(wxHORIZONTAL);
	//topSizer->Add(sizer, 1, wxEXPAND);
	topSizer->Add(properties, 1, wxALL|wxEXPAND, 10);
	properties->CreateGrid(0, 2);
	properties->SetColLabelValue(0, _("Property"));
	properties->SetColLabelValue(1, _("Value"));
	properties->EnableEditing(true);

	currentEntity = NULL;

	SetSizer(topSizer);
	SetAutoLayout(true);
}

QPropEntity::~QPropEntity()
{
}

void QPropEntity::OnSize(wxSizeEvent &event)
{
	wxPanel::OnSize(event);
	properties->FitInside();
	wxSize size = properties->GetClientSize();
	int w = (size.GetWidth()-properties->GetRowLabelSize()-15)/2;
	properties->SetColSize(0, w);
	properties->SetColSize(1, w);
}

void QPropEntity::OnUpdate(wxView* sender, wxObject* hint)
{
	int flags = 0;
	Object *scope = NULL;

	Selector *selector = &GetMainFrame()->GetSelector();
	if(hint && hint->IsKindOf(CLASSINFO(QDocHint)))
	{
		QDocHint *qhint = static_cast<QDocHint*> (hint);
		flags = qhint->flags;
		scope = qhint->scope;
	}

	if (flags & DUAV_NOQPROPPAGES /*|| !active*/)
		return;

	if(scope != NULL && !(flags & (DUAV_OBJSSEL | DUAV_OBJENTMODATTRIB)))
		return;

	lightButton->Enable(false);

	if(selector->GetNumMSelectedObjects() == 1)
	{
		Object *object = selector->GetMSelectedObjects()[0].GetPtr();
		currentEntity = object->GetEntityPtr();
	}
	else
	{
		Object *rootObject = GetMainFrame()->GetDeskTopDocument()->GetRootObjectPtr();
		if(rootObject)
			currentEntity = rootObject->GetEntityPtr();
		else
			currentEntity = NULL;
	}

	// Disable the controls.
	if(currentEntity == NULL)
	{
		lightButton->Enable(false);
		if(properties->GetNumberRows() > 0)
			properties->DeleteRows(0, properties->GetNumberRows());
		properties->Enable(false);
		className->SetValue(wxEmptyString);
		className->Enable(false);
		return;
	}

	// Enable the controls.
	className->Enable(true);
	properties->Enable(true);

	// Delete the rows.
	if(properties->GetNumberRows() > 0)
		properties->DeleteRows(0, properties->GetNumberRows());

	// Delete the keys.
	keys.clear();

	// Read the entity info.
	EntInfo *entInfo = currentEntity->GetEntInfo();
	ASSERT(entInfo);

	for(int i = 0; i < entInfo->GetNumEntries(); i++)
	{
		QEntEntry *entry = entInfo->GetEntryNum(i);
		if(entry->vartype == VAR_NOTUSER)
			continue;

		if(entry->name.CmpNoCase(wxT("_color")) == 0)
			lightButton->Enable(true);

		wxString key = entry->name;
		wxString value = currentEntity->GetKey(entry->name);

		// Check the value.
		if(value.empty() && entry->vartype == VAR_FLAGDEF)
			value = wxT("0");

		if(entry->vartype == VAR_STRDEF)
		{
			for(int j = 0; j < entry->entDef->GetNumEntries(); j++)
			{
				if(value == entry->entDef->GetEntryNum(j)->str)
				{
					value = entry->entDef->GetEntryNum(j)->name;
					break;
				}
			}
		}

		// Add a row.
		properties->AppendRows(1);

		// Get the last row position.
		int row = properties->GetNumberRows()-1;

		// Set the last row values.
		properties->SetCellValue(row, 0, key);
		properties->SetCellValue(row, 1, value);

		// Store the key.
		keys.push_back(key);
	}

	// Add a row to insert new keys.
	properties->AppendRows(1);
	int row = properties->GetNumberRows()-1;
	properties->SetCellValue(row, 0, _("<newentry>"));
	properties->SetCellValue(row, 1, wxT(""));
	properties->SetCellEditor(row, 1, NULL);

	// Set the class name.
	className->SetValue(currentEntity->GetClassName());
}

void QPropEntity::OnCellChange(wxGridEvent &event)
{
	static bool process = false;
	int column = event.GetCol();
	int row = event.GetRow();

	// Avoid recursive processing.
	if(process)
		return;
	process = true;

	// Check if we are adding a new entry.
	if(row == properties->GetNumberRows()-1)
	{
		ASSERT(column == 0 || column == 1);
		if(column == 1)
		{
			// The key must be added first.
			event.Veto();
		}
		else // column == 0
		{
			// Add a new key.
			wxString key = properties->GetCellValue(row, 0);

			EntInfo *entInfo = currentEntity->GetEntInfo();
			ASSERT(entInfo);
			entInfo->AddUserEntry(key);

			// Add a new row to add new keys..
			row++;
			properties->AppendRows(1);
			properties->SetCellValue(row, 0, _("<newentry>"));
			properties->SetCellValue(row, 1, wxT(""));
			properties->SetCellEditor(row, 1, NULL);
		}
	}
	else
	{
		// Modify key or value.
		if(column == 0)
		{
			// Modify a key.
			wxString key = keys[row];
			wxString newKey = properties->GetCellValue(row, 0);
			if(newKey.empty())
			{
				event.Veto();
				wxMessageBox(_("Entity property name cannot be empty"), _("Invalid Property"));
			}
			else if(newKey == key)
			{
				// Nothing changed.
			}
			else
			{
				EntInfo *entInfo = currentEntity->GetEntInfo();
				ASSERT(entInfo);
				entInfo->AddUserEntry(newKey);
				OnUpdate(NULL, NULL);
			}
		}
		else // column == 1
		{
			// Modify a value.
			wxString key = keys[row];
			wxString arg = properties->GetCellValue(row, column);

			Selector *selector = &GetMainFrame()->GetSelector();

			// TODO: Handle multi selection.
			Object *object;
			if(selector->GetNumMSelectedObjects() == 0)
			{
				object = GetMainFrame()->GetDeskTopDocument()->GetRootObjectPtr();
				ASSERT(object->HasEntity());
			}
			else
			{
				object = selector->GetMSelectedObjects()[0].GetPtr();
			}

			Entity *entity = object->GetEntityPtr();

			wxString oldArg = entity->GetKey(key);
			if(!oldArg || arg != oldArg)
			{
				OpEntitySetKey *op = new OpEntitySetKey(object, key, arg);
				GetMainFrame()->CommitOperation(*op);
			}
		}
	}

	// End event handling.
	process = false;
}

